#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <unordered_map>
#include <mutex>
#include "log.hpp"
using websocket_server_t = websocketpp::server<websocketpp::config::asio>;
class Connection {
public:
    using ptr = std::shared_ptr<Connection>;
    struct Client {
        Client(const std::string& user_id, const std::string& session_id)
            : _user_id(user_id), _session_id(session_id) {}
        Client() = default;
        std::string _user_id;
        std::string _session_id;
    };


    void insert(const websocket_server_t::connection_ptr& conn, const std::string& user_id, const std::string& session_id) {
        std::unique_lock<std::mutex> lock(_mutex);
        _uid_connections[user_id] = conn;
        _conn_clients[conn] = Client(user_id, session_id);
        LOG_DEBUG("新增长连接: user_id={}, session_id={}, conn_ptr={}", user_id, session_id, size_t(conn.get()));
    }


    websocket_server_t::connection_ptr connection(const std::string& user_id) {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _uid_connections.find(user_id);
        if (it == _uid_connections.end()) {
            LOG_DEBUG("没有找到连接: user_id={}", user_id);
            return nullptr;
        }
        LOG_DEBUG("找到连接: user_id={}, conn_ptr={}", user_id, size_t(it->second.get()));
        return it->second;
    }


    bool client(const websocket_server_t::connection_ptr& conn, std::string& user_id, std::string& session_id) {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _conn_clients.find(conn);
        if (it == _conn_clients.end()) {
            LOG_DEBUG("没有找到客户端: conn_ptr={}", size_t(conn.get()));
            return false;
        }
        user_id = it->second._user_id;
        session_id = it->second._session_id;
        LOG_DEBUG("找到客户端: user_id={}, session_id={}, conn_ptr={}", user_id, session_id, size_t(conn.get()));
        return true;
    }


    void remove(const websocket_server_t::connection_ptr& conn) {
        std::unique_lock<std::mutex> lock(_mutex);
        auto it = _conn_clients.find(conn);
        if(it == _conn_clients.end()) {
            LOG_DEBUG("没有找到客户端: conn_ptr={}", size_t(conn.get()));
            return;
        }
        std::string user_id = it->second._user_id;
        _conn_clients.erase(it);
        _uid_connections.erase(user_id);
        LOG_DEBUG("删除连接: user_id={}, conn_ptr={}", user_id, size_t(conn.get()));
    }
private:
    std::mutex _mutex;
    std::unordered_map<std::string, websocket_server_t::connection_ptr> _uid_connections; // user_id -> connection_ptr
    std::unordered_map<websocket_server_t::connection_ptr, Client> _conn_clients; // connection_ptr -> Client
};